{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 网格的矩阵表示与"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 基本数组\n",
    "* 命名与定向约定\n",
    "* 辅助数组的生成算法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Poisson 方程模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Galerkin 方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 有限元方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 网格"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "网格类型\n",
    "* 一维\n",
    "* 二维\n",
    "    + 三角形\n",
    "    + 四边形\n",
    "    + 多边形\n",
    "* 三维\n",
    "    + 四面体\n",
    "    + 六面体\n",
    "    + 多面体"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用两个基本数组表示一个网格：\n",
    "\n",
    "* node\n",
    "* cell\n",
    "\n",
    "给出三角形网格的实例，让学生写出其它类型网格的实例。\n",
    "\n",
    "关键概念：\n",
    "* 节点的单元局部编号\n",
    "* 节点的全局编号\n",
    "* 边的局部编号\n",
    "* 边的定向\n",
    "* 单元的定向"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以一个简单的三角形网格为例讲解 edge 生成算法\n",
    "\n",
    "1. 生成所有重复的边 \n",
    "\n",
    "```\n",
    "localEdge = np.array([(1, 2), (2, 0), (0, 1)])\n",
    "totalEdge = cell[:, localEdge].reshape(-1, 2)\n",
    "totalEdge = np.sort(totalEdge, axis=1)\n",
    "\n",
    "\n",
    "totalEdge:\n",
    "\n",
    "[[0 2]\n",
    " [0 1]\n",
    " [1 2]\n",
    " [0 2]\n",
    " [2 3]\n",
    " [0 3]]\n",
    "```\n",
    "\n",
    "2. 用字典排序生成唯一的边，不考虑边的定向问题 \n",
    "\n",
    "```\n",
    "edge, i0, j = unique_row(totalEdge) # 字典排序\n",
    "edge:\n",
    "\n",
    "[[0 1]\n",
    " [0 2]\n",
    " [0 3]\n",
    " [1 2]\n",
    " [2 3]]\n",
    "\n",
    "i0: [1 0 5 2 4]\n",
    "i1: [1 3 5 2 4]\n",
    "\n",
    "j : [1 0 3 1 4 2]\n",
    "cell2edge：[[1， 0, 3]\n",
    "            [1, 4, 2]]\n",
    "\n",
    "\n",
    "edge == totalEdge[i0, :]\n",
    "totalEdge = edge[j, :]\n",
    "```\n",
    "\n",
    "3. 利用 `i0`， `i1` 生成 `edge2cell`\n",
    "\n",
    "```\n",
    "NE = i0.shape[0]\n",
    "edge2cell = np.zeros((NE, 4), dtype=self.itype)\n",
    "i1 = np.zeros(NE, dtype=self.itype) \n",
    "i1[j] = np.arange(E*NC, dtype=self.itype)\n",
    "edge2cell[:, 0] = i0//3 \n",
    "edge2cell[:, 1] = i1//3\n",
    "edge2cell[:, 2] = i0%3 \n",
    "edge2cell[:, 3] = i1%3 \n",
    "```\n",
    "\n",
    "4. 得到定向的边 \n",
    "\n",
    "```\n",
    "edge = cell[edge2cell[:, [0]], localEdge[edge2cell[:, 2]]]\n",
    "```\n",
    "\n",
    "5. 利用 edge2cell 生成 `cell2cell`\n",
    "\n",
    "* 形状\n",
    "* 每个元素代表的意义"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以四边形为例， 生成上述数据结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "多边形的数组结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n0389hJ+Pr0vGADyd9oNSKj+eOkailFKqhNAgUUop5RANEqWUUg7RIFFKKeUQDRKllFIO0SBRSinl\nEA0SpZRHERGTMRUBIjJbRCa5uyaVPw0SpZRSDtEgUUop5RANEqWU04jI7SKyRETOicgFEZmesfwv\nInJARC6JyJqMCdFUCaVBopRyCrHfePUbIA6oBVQDFojIw8BY4BEgGNiMfdoIVUJpkCilnOUuIAz4\nhzHmijEm2RizBRgKTDHGHDDGpAOvA011r6Tk0iBRSjnL7UBcRlhkVRN4T0QSRCQBuAgI9j0WVQLp\n3X+VUs7yG1BDRLxzhMlvwGRjzGduqksVM90jUUo5y4/AaeANEQkUEX8RaQfMAl4WkUYAIlJeRB51\nZ6HKMRokSimnMPYZLHsCdYHjwAmgnzHmK+BN7APvvwN7ga5uK1Q5TA9tKaWcxhhzHOidy/J5wLw8\nniNZ/j3EacWpYqN7JEoppRyiQaKUUsohGiRKKaUcokGilFLKIRokSimlHKJnbalbUkBAQHxycnJI\nQdf39/e3JScnF/iLVUle35Nq8bT1PakWT1vf39//zLVr16rm9pgGibolJScnhxhjCry+iFhKy/qe\nVIunre9JtXja+iKS5xczPbSllFLKIRokSimlHKJBokqFTZs20atXL6pVq4aIMHv27AI/d8qUKYgI\nw4cPz3e9mTNnEh4ejr+/Py1atGDz5s25rjdjxgyaNGlCuXLlKFeuHG3atGHFihU3raOg2y9s7YXp\nmylTptCqVSvKlStHcHAwPXv2ZO/evXmuP2HCBEQk20/VqrkeZi9S7UXty4Jsv1atWjfULiJ07949\nz22ePn2awYMHExwcjL+/PxEREWzcuNHhWqDwfWm1Wnn11Vev/82Eh4czbtw40tNz3oy5aK81Kw0S\nVSokJSURGRnJe++9R0BAQIGf98MPP/Df//6XJk2a5LvewoULGTFiBGPHjmXXrl20bduWrl27cvz4\n8RvWrV69Om+++SY///wzO3bsoGPHjvTu3Zvdu3cXy/YLW3th+iYqKophw4axdetW1q9fj7e3N507\nd+bixYt5Pqd+/fqcPn36+s+ePXvybaMwtRelLwu6/Z9++ilb3T///DMiwp///Odc109ISKBdu3YY\nY1ixYgUHDhxg2rRpVKlSpVheKxSuL998801mzJjB+++/T0xMDO+99x4zZsxgypQpDr/WnDRIVKnQ\n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\nYCOBQObhrceBicaYCRkhMh34FNgO9HdKcUopwDODJBa4Qs4w6Qk+3j5UKl8h1ycVF6vFF+9cPkQr\nVICsdzpIt/jyfT3nXYxYsXwFfLx9bvwQ7QI+3Xzo2rYDzRs4b3wir37IadBffKldz3mn/ubZDx2A\nDlwBRpjxJtu9MIwx3wKFu+RaKVVknngb+YWQyzEV7HsFjeo495qNM2UbYrtJt9iwcKZs3nMMFIfI\n2g3I6wxn7YcsJdj/XpRSbuRxQZJxSmc3IBH7ngk+3j74+vgwsOsj+Pk4fq+g/Jyo2BJzk5MYjFg4\nUbFlvus4ys/Xl4FdH8HXxwcfb/vdQbUfrt8l9Qr2v49uZrxx7rFOpdRNeeyV7TJRgoB+bOajXq90\noVGd+k7/8MyU2/UTYP8GbsTC/rBeXAxyzYWIKWmp7Dt8kGWT16L9YO8H7iHzOhINEaU8gMcGSaac\nt0hxlbyubD9RsSXJvs4dp8nNhLC30H648RYpSin388TBdo+Q7FuB2Kqdia3qnNNaSwrtB6XUzXjc\nGIlSSqmSRYNEKaWUQzRIlFJKOUSDRCmllEM0SJRSSjlEg0QppZRDNEiUUko5RINEKaWUQzRIlFJK\nOUSDRCmllEM0SJRSSjlEg0QppZRDNEiUUko5RINEKaWUQzRIlFJKOUSDRCmllEM0SJRSSjlEg0Qp\npZRDNEiUUko5RINEKaWUQzRIlFJKOUSDRCmllEM0SJRSSjlEg0QppZRDNEiUUko5RINEKaWUQzRI\nlFJKOUSDRCmllEM0SJRSSjlEg0QppZRDNEiUUko5RINEKaWUQzRIlFJKOcTb3QUU1JfDV3J0y3FS\nr6YRVCWQds+1pMXAJi6vY8/SGDa+vY3LJ38nqEogvd99iJqtq7u8jgtHLjGz0xwiut9Bn+ndXNr2\npd8us+Ll7zix8xRevl5EdL+Dh/7dAS9v130vEZEo4G4gPWPRSWNMfZcVoJS6rsQEyT0v3MXDb3XB\n28+bc4cuMLvvIkIbhxDWJMRlNRzeeIxvJ2+i76weVGsWStKZJJe1ndOKsd9R7c6q7mn75e8IrFyG\nF3cNJfn3FOb1X8xPs6O5+6nmri5luDHmI1c3qpTKrsQc2qpSvzLefvbcExFEhIvHElxaw4b/bOW+\nkW24vUUYFotQLrQs5ULLurQGsO8V+Zf3I7x9DZe3DZBw/DKNet6Bj783ZasEUvf+Wpz79YJbalFK\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7faec1a84630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt \n",
    "import matplotlib.gridspec as gridspec\n",
    "%matplotlib inline\n",
    "from fealpy.mesh.PolygonMesh import PolygonMesh\n",
    "\n",
    "def labels(n):\n",
    "    r = [str(i)+':' for i in range(n)]\n",
    "    return r\n",
    "\n",
    "node = np.array([\n",
    "    [0, 0],\n",
    "    [1, 0],\n",
    "    [2, 0],\n",
    "    [0, 1],\n",
    "    [1, 1],\n",
    "    [2, 1],\n",
    "    [0, 2],\n",
    "    [1, 2],\n",
    "    [2, 2]], dtype=np.float)\n",
    "cell = np.array([1, 4, 0, 3, 0, 4, 1, 2, 5, 4, 3, 4, 7, 6, 4, 5, 8, 7], dtype=np.int)\n",
    "cellLocation = np.array([0, 3, 6, 10, 14, 18], dtype=np.int)\n",
    "\n",
    "mesh = PolygonMesh(node, cell, cellLocation)\n",
    "node = mesh.entity('node')\n",
    "edge = mesh.entity('edge')\n",
    "cell = mesh.ds.cell\n",
    "cellLocation = mesh.ds.cellLocation\n",
    "edge = mesh.ds.edge\n",
    "cell2edge = mesh.ds.cell_to_edge()\n",
    "edge2cell = mesh.ds.edge_to_cell()\n",
    "\n",
    "gs = gridspec.GridSpec(2, 2)\n",
    "axes = [plt.subplot(gs[:, 0]), plt.subplot(gs[0, 1]), plt.subplot(gs[1, 1])]\n",
    "mesh.add_plot(axes[0])\n",
    "mesh.find_node(axes[0], showindex=True, markersize=25, fontsize=12)\n",
    "mesh.find_edge(axes[0], showindex=True, markersize=50, fontsize=12)\n",
    "mesh.find_cell(axes[0], showindex=True, markersize=100, fontsize=12)\n",
    "axes[0].set_title('mesh', y=1)\n",
    "\n",
    "for ax in axes:\n",
    "    ax.axis('tight')\n",
    "    ax.axis('off')\n",
    "table = axes[1].table(cellText=cell.reshape(1, -1),  loc='center')\n",
    "axes[1].set_title('cell', y=0.6)\n",
    "table.set_fontsize(14)\n",
    "table.scale(1.4, 1.4)\n",
    "table = axes[2].table(cellText=cellLocation.reshape(1, -1), loc='center')\n",
    "axes[2].set_title('cellLocation', y=0.6)\n",
    "table.set_fontsize(14)\n",
    "table.scale(1.4, 1.4)\n",
    "#plt.tight_layout(pad=1, w_pad=0.5, h_pad=1)\n",
    "plt.savefig('/home/why/polyedgedata1.pdf')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. to"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  },
  "latex_envs": {
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 0
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
